package com.smf.lsc.authorization.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultUserAuthenticationConverter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import com.smf.lsc.authorization.security.properties.OAuth2Properties;
import com.smf.lsc.authorization.security.service.MyUserDetailsService;
import com.smf.lsc.authorization.security.service.jwt.MyJwtTokenEnhancer;

/**
 * Created on 2021/11/19.
 *
 * @author ln
 * @since 1.0
 * 
 * TokenStore设置，支持redis存储token及默认token模式，通过security.oauth2.storeType切换
 * 
 */
@Configuration
public class TokenStoreConfig {
	
	
	/**
     * redis TOKEN配置信息
     */
	@Configuration
    @ConditionalOnProperty(prefix = "lsc.security.oauth2", name = "storeType", havingValue = "redis")
	public static class RedisTokenCofnig{
		
		/**
	     * redis连接工厂
	     */
	    @Autowired
	    private RedisConnectionFactory redisConnectionFactory;
	
	    /**
	     * 用于存放token
	     * @return
	     */
	    @Bean
	//    @ConditionalOnProperty(prefix = "lsc.security.oauth2", name = "storeType", havingValue = "redis")
	    public TokenStore redisTokenStore() {
	        return new RedisTokenStore(redisConnectionFactory);
	    }
	    
	}
    

    /**
     * jwt TOKEN配置信息
     */
    @Configuration
    @ConditionalOnProperty(prefix = "lsc.security.oauth2", name = "storeType", havingValue = "jwt", matchIfMissing = true)
    public static class JwtTokenCofnig{

        @Autowired
        private OAuth2Properties oAuth2Properties;

        @Autowired
        private MyUserDetailsService userDetailsService;
        
        /**
         * 使用jwtTokenStore存储token
         * @return
         */
        @Bean
        public TokenStore jwtTokenStore(){
            return new JwtTokenStore(jwtAccessTokenConverter());
        }

        /**
         * 用于生成jwt
         * @return
         */
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter(){
        	//设置自定义用户信息转换器，设置Principal为userDetailsService，默认getPrincipal是username
        	JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            DefaultAccessTokenConverter accessTokenConverter = (DefaultAccessTokenConverter)converter.getAccessTokenConverter();
            DefaultUserAuthenticationConverter defaultUserAuthenticationConverter = new DefaultUserAuthenticationConverter();
            defaultUserAuthenticationConverter.setUserDetailsService(userDetailsService);
            accessTokenConverter.setUserTokenConverter(defaultUserAuthenticationConverter);
            converter.setSigningKey(oAuth2Properties.getJwtSigningKey());//生成签名的key
            return converter;
            
            //默认用户信息转换器，，默认getPrincipal是username
//          JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
//          accessTokenConverter.setSigningKey(oAuth2Properties.getJwtSigningKey());//生成签名的key
//          return accessTokenConverter;
        }

        /**
         * 用于扩展JWT
         * @return
         */
        @Bean
        @ConditionalOnMissingBean(name = "jwtTokenEnhancer")
        public TokenEnhancer jwtTokenEnhancer(){
            return new MyJwtTokenEnhancer();
        }

    }
}
